<script setup lang="ts">
import { addShapeAbsolute, addShapeRelative } from "@/utils/param-model-regen";
import { getParamModels } from '@/utils/service';
import { AmbientLight, AxesHelper, GridHelper, PerspectiveCamera, PointLight, Scene, WebGLRenderer } from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

/** 渲染器 */
const renderer = new WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
const containerRef = ref<Element>()
function mountThree(el: Element) {
  el.append(renderer.domElement)
}
renderer.setClearColor(0xeeeeee)
onMounted(() => {
  const el = containerRef.value
  el && mountThree(el)
})

/** 摄像机 */
const camera = new PerspectiveCamera(undefined, window.innerWidth / window.innerHeight, 10, 140000);
camera.position.set(1400, -600, 500);
camera.up.set(0, 0, 1)

/** 场景 */
const scene = new Scene();

/** 渲染模型 */
function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
/** 添加光源 */
function addLight() {
  const ambientLight = new AmbientLight()
  ambientLight.position.set(200, 200, 1400);
  scene.add(ambientLight);

  const pointLight = new PointLight()
  pointLight.position.set(600, 200, 1400)
  scene.add(pointLight)
}
/** 监听页面缩放 */
function listenerResize() {
  window.addEventListener('resize', function () {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }, false);
}
/** 添加坐标轴 */
function addAxesHelper() {
  var axesHelper = new AxesHelper(1000);
  scene.add(axesHelper);
}
/** 添加网格 */
function addGridHelper() {
  const gridHelper = new GridHelper(5000, 40);
  gridHelper.rotateX(Math.PI / 2)
  scene.add(gridHelper);
}
/** 添加场景控制器 */
function addControls() {
  const orbit = new OrbitControls(camera, renderer.domElement);
  orbit.enableZoom = true;
}
/** 通过绝对位置还原 */
function addShapeUseAbs() {
  getParamModels().then(models => {
    const shapes = models.map((model) => {
      return addShapeAbsolute(model)
    })
    scene.add(...shapes)
  })
}
/** 通过相对位置还原  */
function addShapeUseRel() {
  getParamModels().then(models => {
    const shapes = models.map((model) => {
      return addShapeRelative(model)
    })
    scene.add(...shapes)
  })
}

addShapeUseAbs()
addShapeUseRel()
addAxesHelper()
addGridHelper()
addControls()
listenerResize()
addLight()
render()

</script>

<template>
  <Teleport to="body">
    <div :class="$style.three" :ref="(el) => (containerRef = el as Element)"></div>
  </Teleport>
</template>

<style module>
.three {
  position: absolute;
  z-index: 1;
}
</style>
